"""
Trading logger with structured output and error handling.
"""

import os
import csv
import logging
from datetime import datetime
import pytz
from decimal import Decimal


class TradingLogger:
    """Enhanced logging with structured output and error handling."""

    def __init__(self, exchange: str, ticker: str, log_to_console: bool = False):
        self.exchange = exchange
        self.ticker = ticker
        # Ensure logs directory exists at the project root
        project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
        logs_dir = os.path.join(project_root, 'logs')
        os.makedirs(logs_dir, exist_ok=True)

        # Log file paths inside logs directory
        self._logs_dir = logs_dir
        self.log_file = os.path.join(self._logs_dir, f"{exchange}_{ticker}_orders.csv")
        self.debug_log_file = os.path.join(self._logs_dir, f"{exchange}_{ticker}_activity.log")
        self.timezone = pytz.timezone(os.getenv('TIMEZONE', 'Asia/Shanghai'))
        self.logger = self._setup_logger(log_to_console)
        # Structured context
        self._addr = ""
        self._account_id = ""

    def set_context(self, context: str):
        """Set address context (kept for backward compatibility)."""
        ctx = (context or "").strip()
        # Try to parse [addr=...] if passed in
        if ctx.startswith("[addr="):
            self._addr = ctx[1:-1].split("=", 1)[1]
        else:
            self._addr = ctx

    def set_address(self, address: str):
        self._addr = (address or "").strip()

    def set_account_id(self, account_id: str):
        self._account_id = (account_id or "").strip()
        # Re-point files to account-scoped files to avoid mixed accounts and ensure headers
        if self._account_id:
            base_prefix = f"{self.exchange}_{self.ticker}_{self._account_id}"
            self.log_file = os.path.join(self._logs_dir, f"{base_prefix}_orders.csv")
            self.debug_log_file = os.path.join(self._logs_dir, f"{base_prefix}_activity.log")

    def _compose_prefix(self) -> str:
        parts = []
        if self._addr:
            parts.append(f"[addr={self._addr}]")
        if self._account_id:
            parts.append(f"[accountId={self._account_id}]")
        return " ".join(parts)

    def _setup_logger(self, log_to_console: bool) -> logging.Logger:
        """Setup the logger with proper configuration."""
        logger = logging.getLogger(f"trading_bot_{self.exchange}_{self.ticker}")
        logger.setLevel(logging.INFO)

        # Prevent duplicate handlers
        if logger.handlers:
            return logger

        class TimeZoneFormatter(logging.Formatter):
            def __init__(self, fmt=None, datefmt=None, tz=None):
                super().__init__(fmt=fmt, datefmt=datefmt)
                self.tz = tz

            def formatTime(self, record, datefmt=None):
                dt = datetime.fromtimestamp(record.created, tz=self.tz)
                if datefmt:
                    return dt.strftime(datefmt)
                return dt.isoformat()

        formatter = TimeZoneFormatter(
            "%(asctime)s.%(msecs)03d - %(levelname)s - %(message)s",
            datefmt="%Y-%m-%d %H:%M:%S",
            tz=self.timezone
        )

        # File handler
        file_handler = logging.FileHandler(self.debug_log_file)
        file_handler.setLevel(logging.INFO)
        file_handler.setFormatter(formatter)
        logger.addHandler(file_handler)

        # Console handler if requested
        if log_to_console:
            console_handler = logging.StreamHandler()
            console_handler.setLevel(logging.INFO)
            console_handler.setFormatter(formatter)
            logger.addHandler(console_handler)

        return logger

    def log(self, message: str, level: str = "INFO"):
        """Log a message with the specified level."""
        prefix = self._compose_prefix()
        if prefix:
            message = f"{prefix} {message}"
        if level.upper() == "DEBUG":
            self.logger.debug(message)
        elif level.upper() == "INFO":
            self.logger.info(message)
        elif level.upper() == "WARNING":
            self.logger.warning(message)
        elif level.upper() == "ERROR":
            self.logger.error(message)
        else:
            self.logger.info(message)

    def log_transaction(self, order_id: str, side: str, quantity: Decimal, price: Decimal, status: str):
        """Log a transaction to CSV file."""
        try:
            timestamp = datetime.now(self.timezone).strftime("%Y-%m-%d %H:%M:%S")
            row = [timestamp]
            # Include accountId column when available
            if self._account_id:
                row.append(self._account_id)
            row.extend([order_id, side, quantity, price, status])

            # Check if file exists to write headers
            file_exists = os.path.isfile(self.log_file)

            with open(self.log_file, 'a', newline='', encoding='utf-8') as csvfile:
                writer = csv.writer(csvfile)
                if not file_exists:
                    headers = ['Timestamp']
                    if self._account_id:
                        headers.append('AccountID')
                    headers.extend(['OrderID', 'Side', 'Quantity', 'Price', 'Status'])
                    writer.writerow(headers)
                writer.writerow(row)

        except Exception as e:
            self.log(f"Failed to log transaction: {e}", "ERROR")
